from PySide6.QtSql import QSqlDatabase, QSqlQuery

"""
增、删、改、查 数据库操作类。
"""
class SqlQueryClass():

    def __init__(self) -> None:
        self.query = QSqlQuery()
        self.tableName = 'receive_file'
    
    #=======================================================================================#
    ###
    ######## 1.增
    
    """
    向{self.tableName}表中插入一条记录。

    Args:
        itemObj (dict): 包含以下键值对的字典：
            - file_id (str): 文件ID。
            - date (str): 日期。
            - title (str): 文件标题。
            - file_number (str): 文件编号。
            - file_type (str): 文件类型。
            - government_unit (str): 政府单位。
            - file (str): 文件内容。
            - src (str): 文件来源。

    Returns:
        bool: 插入操作是否成功。如果成功返回True，否则返回False。

    """
    def insertOneItem(self,itemObj):
        id,file_id,date,title,file_number,file_type,government_unit,file,src = itemObj.values()
        
        sql = f"insert into {self.tableName} (file_id, date, title, file_number, file_type, government_unit, file, src) values"  
        sql += f"('{file_id}','{date}', '{title}', '{file_number}', '{file_type}', '{government_unit}', '{file}', '{src}')"
        print('insertOneItem::', sql)
        isQuery = self.query.exec(sql)
        # 检查是否有错误发生
        if self.query.lastError().isValid():
            print(self.query.lastError().text())       
        return isQuery
    #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#
    def insertOneItemToSave_file_table(self,itemObj):
        id,file_id,year,term,title,box_id,page,file_type,government_unit,date,file_number,src = itemObj.values()
        sql = "insert into save_file (id, file_id, year, term, title, box_id, page, file_type, government_unit, date, file_number, src) values"  
        sql += f"('{id}','{file_id}','{year}','{term}', '{title}', '{box_id}', '{page}', '{file_type}', '{government_unit}', '{date}', '{file_number}', '{src}')"
        print('insertOneItemToSave_file_table::', sql)
        isQuery = self.query.exec(sql)
        # 检查是否有错误发生
        if self.query.lastError().isValid():
            print(self.query.lastError().text())       
        return isQuery
    ###
    #=======================================================================================#

    #=======================================================================================#
    ###
    ######## 2.删
    def deleteOneItem(self,id):
        sql = f"delete from {self.tableName} where id={id}"
        print('deleteOneItem::', sql)
        isQuery = self.query.exec(sql)
        # 检查是否有错误发生
        if self.query.lastError().isValid():
            print(self.query.lastError().text())
        self.query.exec()    
        return isQuery
    ###
    #=======================================================================================#
    
    #=======================================================================================#
    ###
    ######## 3.改
    """
    更新数据库中的单个文件信息。

    Args:
        itemObj (dict): 包含文件信息的字典，应包含以下键：
            - id (int): 文件的唯一标识符。
            - file_id (str): 文件的ID。
            - date (str): 文件的日期。
            - title (str): 文件的标题。
            - file_number (str): 文件的编号。
            - file_type (str): 文件的类型。
            - government_unit (str): 政府单位。
            - file (str): 文件内容。
            - src (str): 文件来源。

    Returns:
        bool: 表示是否成功执行了SQL语句。

    Raises:
        无特定异常抛出，但可能由于数据库操作失败而抛出相关异常。
    """
    def updateOneItem(self,itemObj):
        print('updateOneItem::', itemObj.values())
        id,file_id,date,title,file_number,file_type,government_unit,file,src = itemObj.values()
        
        sql = f"update {self.tableName} set "  
        sql += f"date='{date}', file_id='{file_id}', title='{title}', file_number='{file_number}', file_type='{file_type}',"
        sql += f"government_unit='{government_unit}', file='{file}', src='{src}' where id={id}"
        print('updateOneItem::', sql)
        isQuery = self.query.exec(sql)
        # 检查是否有错误发生
        if self.query.lastError().isValid():
            print(self.query.lastError().text())
        self.query.exec()    
        return isQuery
    #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#
    def updateOneItemToSave_file_table(self,itemObj):
        print('updateOneItem::', itemObj.values())
        id,file_id,year,term,title,box_id,page,file_type,government_unit,date,file_number,src = itemObj.values()
        
        sql = f"update {self.tableName} set "  
        sql += f"date='{date}',year='{year}',term='{term}',box_id='{box_id}',page='{page}', file_id='{file_id}', title='{title}', file_number='{file_number}', file_type='{file_type}',"
        sql += f"government_unit='{government_unit}', src='{src}' where id={id}"
        print('updateOneItem::', sql)
        isQuery = self.query.exec(sql)
        # 检查是否有错误发生
        if self.query.lastError().isValid():
            print(self.query.lastError().text())
        self.query.exec()    
        return isQuery
    #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#
    """
    根据年份更新 receive_file 表中所有文件的 file_id。

    Args:
        year (str): 要更新 file_id 的年份，格式为 'YYYY'。

    Returns:
        None: 此函数不返回任何值，直接更新数据库。

    """
    def updateAllfileId(self,year):
        update_query = QSqlQuery()
        
        self.query.exec(f"select id, file_id from {self.tableName} where date >= '{year}-01-01' AND date <= '{year}-12-31' order by id")  # 假设按照id排序
        num = 0
        
        while self.query.next():
            num += 1
            id_value = self.query.value("id")
            file_id_value = f"{num:04d}"
            
            update_query.prepare(f"UPDATE {self.tableName} SET file_id = :file_id WHERE id = :id")
            update_query.bindValue(":id", id_value)
            update_query.bindValue(":file_id", file_id_value)
            update_query.exec()
        self.query.exec()
    ###
    #=======================================================================================#
    #=======================================================================================#
    ###
    ######## 4.查
    """
    获取 receive_file 表中记录的总数。

    Args:
        无参数。

    Returns:
        int: receive_file 表中记录的总数。

    """
    def getTotalRecordCount(self):
        self.query.exec(f'select count(*) from {self.tableName}')
        self.query.next()
        rowCount = self.query.value(0)
        print('rowCount=' + str(rowCount))
        return rowCount
    #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#
    def getAll(self,year):
        update_query = QSqlQuery()
        
        self.query.exec(f"select id, file_id from {self.tableName} where date >= '{year}-01-01' AND date <= '{year}-12-31' order by id")  # 假设按照id排序
        num = 0
        
        while self.query.next():
            num += 1
            id_value = self.query.value("id")
            file_id_value = f"{num:04d}"
            
            update_query.prepare(f"UPDATE {self.tableName} SET file_id = :file_id WHERE id = :id")
            update_query.bindValue(":id", id_value)
            update_query.bindValue(":file_id", file_id_value)
            update_query.exec()
        self.query.exec()
    
    ###
    #=======================================================================================#

if __name__ == "__main__":
    import os
    from PySide6.QtWidgets import QWidget, QMessageBox
    os.chdir(os.path.dirname(__file__))
    # 打开数据库，该库由qt_createSql.py脚本创建。
    db = QSqlDatabase.addDatabase('QSQLITE')
    db.setDatabaseName('../db/filedatabase.db')
    if db.open() is not True:
        QMessageBox.critical(QWidget, 'open error', '数据库打开失败')
        exit()
        
    itemObj = {
        "id": 37,
        "data": "2021-08-31",
        "file_id": "0012",
        "title": "测试标题",
        "number": 100,
        "type": "测试类型",
        "unit": "测试单位",
        "file": "测试文件",
        "src": "测试来源"
    }
    sqlQuery = SqlQueryClass()
    #sqlQuery.updateOneItem(itemObj)
    #sqlQuery.updateAllfileId("2024")
    sqlQuery.getTotalRecordCount()